<?php

declare(strict_types=1);
/**
 * This file is part of habo_new_media.
 *
 * @link     https://www.berlen.cn/
 * @contact  tech@berlen.cn
 * @license  http://gitlab.rehou.cn/habo/habo_new_media/-/blob/master/README.md
 */
namespace app\service\fetch\kuaishou;

use app\enum\CommandEnum;
use app\enum\CommonEnum;
use app\enum\ConfigEnum;
use app\enum\KuaiShouEnum;
use app\model\ClientAccountModel;
use app\model\KsAppDspModel;
use app\model\KsAppModel;
use app\model\KsOcpxConversionModel;
use app\model\KsPicModel;
use app\service\client\AccountService;
use app\service\fetch\MediaInterface;
use app\service\fetch\MediaService;
use app\service\kuaishou\AdvertiserService;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;
use think\facade\Cache;
use think\Model;

final class OcpxConversionOcpxTypesService extends MediaService implements MediaInterface
{
    /**
     * @var string 数据拉取key
     */
    protected const FETCH_KEY = ConfigEnum::CACHE_CONFIG[KuaiShouEnum::LIST_CONFIG_LOCK_KEY]['ocpx_conversion_ocpx_types'];

    /**
     * 获取转化目标.
     *
     * @param string $advertiserId 账户id
     */
    public static function getOcpxConversionOcpxTypes(string $advertiserId = ''): bool
    {
        try {
            $model = '';
            // 获取账户信息
            $obj = AccountService::getAccountModel(0, $advertiserId);
            if (! $obj instanceof ClientAccountModel || ! $obj->getKey()) {
                return self::setError('账户数据不存在');
            }
            $params = self::getParams($advertiserId);
            foreach ($params as $param) {
                $result = self::getList($advertiserId, $param);
                if ($result === false) {
                    return false;
                }
                if (count($result['data']['ocpx_types']) == 0) {
                    return true;
                }
                foreach ($result['data']['ocpx_types'] as $item) {
                    $model = self::getInfo($advertiserId, $param, $item['ocpx_action_type']);
                    if (! $model instanceof KsOcpxConversionModel || ! $model->getKey()) {
                        $model = new KsOcpxConversionModel();
                    }
                    $item['advertiser_id'] = $advertiserId;
                    $item['account_id'] = $obj->getKey();
                    $model->setAttrs([
                        'advertiser_id' => $advertiserId,
                        'account_id' => $obj->getKey(),
                        'app_id' => $param['app_id'],
                        'scene_ids' => $param['scene_ids'][0],
                        'scene_category' => $param['scene_category'],
                        'campaign_type' => $param['campaign_type'],
                        'ocpx_action_type' => $item['ocpx_action_type'],
                        'name' => $item['name'],
                    ]);
                    if (! $model->save()) {
                        throw new \Exception('保存数据出错');
                    }
                }
            }
            if ($model instanceof KsOcpxConversionModel) {
                self::pushDeepList($advertiserId);
            }

            return true;
        } catch (\Exception $e) {
            return self::setError($e->getMessage());
        }
    }

    /**
     * 进深度队列.
     * @param string $advertiserId 账户id
     */
    private static function pushDeepList(string $advertiserId = '')
    {
        Cache::store('redis')->handler()->rPush(CommandEnum::DEEP_OCPX_REDIS_LIST_KEY, $advertiserId);
    }

    /**
     * 获取参数.
     *
     * @param string $advertiserId 账户id
     */
    private static function getParams(string $advertiserId = ''): array
    {
        $params = [];
        // 场景分类
        $scene_category = 0;    // 普通创编
        // 暂时只拉提升应用安装和销售线索
        $campaign_types = array_keys(KuaiShouEnum::CAMPAIGN_TYPE);
        // 投放资源位置
        $scene_ids = array_keys(KuaiShouEnum::SCENE_IDS_TYPE);
        $list = KsAppModel::where(['advertiser_id' => $advertiserId])->column('app_id');
        $listNew = KsAppDspModel::where(['advertiser_id' => $advertiserId])->column('app_id');
        $appIds = array_merge($list, $listNew);
        foreach ($campaign_types as $campaign_type) {
            foreach ($scene_ids as $scene_id) {
                if ($campaign_type == 2) {
                    if (! empty($appIds)) {
                        foreach ($appIds as $appId) {
                            $params[] = [
                                'advertiser_id' => $advertiserId,
                                'scene_category' => $scene_category,
                                'app_id' => $appId,
                                'campaign_type' => $campaign_type,
                                'scene_ids' => [$scene_id],
                            ];
                        }
                    }
                } else {
                    $params[] = [
                        'advertiser_id' => $advertiserId,
                        'scene_category' => $scene_category,
                        'app_id' => 0,
                        'campaign_type' => $campaign_type,
                        'scene_ids' => [$scene_id],
                    ];
                }
            }
        }
        return $params;
    }

    /**
     * 获取转化列表.
     * @param string $advertiserId 账户id
     * @param array $params 参数
     * @return bool|mixed|string
     */
    private static function getList(string $advertiserId = '', array $params = [])
    {
        $token = AccountService::getToken(CommonEnum::KS_MEDIA, $advertiserId);
        if (! $token) {
            return self::setError('token获取失败');
        }
        $headers = [
            'Access-Token' => $token,
            'Content-Type' => 'application/json',
        ];
        return AdvertiserService::getOcpxConversionOcpxTypes($headers, $params);
    }

    /**
     * 获取目标信息.
     * @param string $advertiserId 账户id
     * @param array $params 参数
     * @param int $ocpxActionType 优化目标
     * @return null|array|KsPicModel|mixed|Model
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    private static function getInfo(string $advertiserId = '', array $params = [], int $ocpxActionType = 0)
    {
        $where = [
            ['advertiser_id', '=', $advertiserId],
            ['campaign_type', '=', $params['campaign_type']],
            ['scene_category', '=', $params['scene_category']],
            ['scene_ids', '=', $params['scene_ids'][0]],
            ['app_id', '=', $params['app_id']],
            ['ocpx_action_type', '=', $ocpxActionType],
        ];
        return (new KsOcpxConversionModel())->where($where)->field(true)->find();
    }
}
